<?php

namespace App\Admin\Service\Base;

use App\Common\Enums\Base\AdministratorsEnumStatus;
use App\Common\Exception\ApiMessageException;
use App\Common\Interfaces\AdminLoginServiceInterface;
use App\Common\Model\Base\Administrators;
use App\Common\Model\Model;
use App\Common\Util\AdminAuth;
use App\Common\Util\TP;
use Psr\SimpleCache\InvalidArgumentException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 系统默认登陆实现
 *
 * Class DefaultLoginService
 */
class DefaultLoginService implements AdminLoginServiceInterface
{
    /**
     * @param string $sign
     * @param bool   $isStrict
     *
     * @return AdminLoginServiceInterface
     * @throws \Exception
     * @deprecated
     */
    public static function getLoginService(string $sign, bool $isStrict = false): AdminLoginServiceInterface
    {
        $loginMap = TP::config('admin_login');

        $classname = $loginMap[$sign] ?? null;
        if (!$classname && $isStrict) {
            throw new \Exception("登录失败！");
        }

        $classname = $classname ?: $loginMap[''];
        $class     = new $classname();

        if (!$class instanceof AdminLoginServiceInterface) {
            throw new \Exception(sprintf("%s登录未实现 %s 接口", $classname, AdminLoginServiceInterface::class));
        }

        return $class;
    }


    /**
     * @param array $data
     *
     * @return void
     * @throws ApiMessageException
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function login(array $data): void
    {
       if (empty($data['account']) || !is_string($data['account']) || strlen($data['account']) < 1){
           throw new ApiMessageException('请输入正确的账号');
       }

       if (empty($data['password']) || !is_string($data['password']) || strlen($data['password']) < 6){
           throw new ApiMessageException('请输入正确的密码');
       }

        $loginLimitKey      = "LoginLimit:{$data['account']}";
        $wrongPasswordTimes = TP::cache()->get($loginLimitKey, 0);
        if ($wrongPasswordTimes > 5) {
            throw new ApiMessageException('密码错误次数超过5次，10分钟后再试');
        }

        /** @var Administrators $administrators */
        $administrators = Administrators::where('account', $data['account'])->find();

        if (!$administrators) {
            throw new ApiMessageException("账号或密码错误");
        }

        if (!password_verify($data['password'], $administrators->password)) {
            TP::cache()->set($loginLimitKey, $wrongPasswordTimes + 1, 600);
            throw new ApiMessageException("账号或密码错误");
        }

        if ($administrators->status != AdministratorsEnumStatus::Normal->value) {
            throw new ApiMessageException("账号被冻结,请联系相关管理人员解冻");
        }

        TP::cache()->delete($loginLimitKey);
        $administrators->lately_time = date('Y-m-d H:i:s');
        $administrators->save();

        AdminAuth::save($administrators);
    }

    /**
     * 登录页面
     *
     * @return string
     */
    public function loginView(): string
    {
        return "Base/Login/login";
    }

    /**
     * @param int $id
     *
     * @return void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException|ApiMessageException
     */
    public function gotoAccount(int $id): void
    {
        $administrators = Administrators::find($id);
        if (!$administrators) {
            throw new ApiMessageException("账号不存在");
        }

        LoginAccountService::gotoAccount($administrators);
    }
}